package club.xyes.zkh.ecommerce.service.impl;

import club.xyes.zkh.ecommerce.commons.dto.Tuple2;
import club.xyes.zkh.ecommerce.commons.entity.Shop;
import club.xyes.zkh.ecommerce.commons.entity.ShopMembershipLevel;
import club.xyes.zkh.ecommerce.commons.entity.User;
import club.xyes.zkh.ecommerce.commons.entity.UserMembership;
import club.xyes.zkh.ecommerce.commons.exception.DiscountException;
import club.xyes.zkh.ecommerce.commons.exception.ResourceNotFoundException;
import club.xyes.zkh.ecommerce.dao.mapper.UserAccessShopLogMapper;
import club.xyes.zkh.ecommerce.dao.mapper.UserMembershipMapper;
import club.xyes.zkh.ecommerce.service.UserMembershipService;
import club.xyes.zkh.ecommerce.service.adapter.impl.UserMembershipSingleDependencyMapperAdapterImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
 * Create by 郭文梁 2019/4/18 0018 14:45
 * UserMembershipServiceImpl
 * 用户会员等级先关业务行为实现
 *
 * @author 郭文梁
 * @data 2019/4/18 0018
 */
@Service
public class UserMembershipServiceImpl extends UserMembershipSingleDependencyMapperAdapterImpl implements UserMembershipService {
    private final UserMembershipMapper mapper;
    private final UserAccessShopLogMapper userAccessShopLogMapper;

    @Autowired
    public UserMembershipServiceImpl(UserMembershipMapper mapper,
                                     UserAccessShopLogMapper userAccessShopLogMapper) {
        super(mapper);
        this.mapper = mapper;
        this.userAccessShopLogMapper = userAccessShopLogMapper;
    }

    @Override
    public List<UserMembership> findByUserIdFetchAll(Integer userId) {
        return mapper.selectByUserIdFetchAll(userId);
    }

    @Override
    public List<UserMembership> findByUserIdAndShopIdFetchAll(Integer userId, Integer shopId) {
        return mapper.selectByUserIdAndShopIdFetchAll(userId, shopId);
    }

    @Override
    public boolean isMembership(User user, Shop shop) {
        return mapper.countByUserIdAndShopId(user.getId(), shop.getId()) > 0;
    }

    @Override
    public Tuple2<UserMembership, Integer> getDiscount(Integer id, User user, Shop shop, int fee) throws DiscountException {
        if (id == null) {
            return Tuple2.of(null, null);
        }
        UserMembership membership = getFetchAll(id);
        if (membership == null) {
            throw new ResourceNotFoundException(UserMembership.class, id);
        }
        ShopMembershipLevel level = membership.getLevel();
        checkAvailable(membership, user, shop);

        BigDecimal rate = new BigDecimal(level.getDiscountRate());
        BigDecimal feeBigDecimal = BigDecimal.valueOf(fee);
        BigDecimal disCountResult = feeBigDecimal.subtract(rate.multiply(feeBigDecimal));
        return Tuple2.of(membership, disCountResult.intValue());
    }


    /**
     * 检查会员优惠可用性
     *
     * @param membership 会员对象
     * @param user       用户
     * @param shop       商铺
     */
    private void checkAvailable(UserMembership membership, User user, Shop shop) throws DiscountException {
        if (!Objects.equals(membership.getUserId(), user.getId())) {
            //会员定义与用户不匹配
            throw new DiscountException(String.format("The userId of UserMembership is [%s], but your id is [%s]", membership.getUserId(), user.getId()));
        }
        ShopMembershipLevel level = membership.getLevel();
        Integer membershipShopId = level.getMembership().getShopId();
        if (!Objects.equals(shop.getId(), membershipShopId)) {
            //该会员不是这个商铺的会员
            throw new DiscountException(String.format("The shopId of UserMembership is [%s], but current shop id is [%s]", membershipShopId, shop.getId()));
        }
    }
}
